package simulaco.dao;

import gminet.infra.dao.DataAccessObject;
import gminet.infra.db.TransactionException;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import simulaco.dto.ConcursoNivel;
import simulaco.dto.SimuladoModelo;
import simulaco.dto.Situacao;


public class SimuladoModeloDAO extends DataAccessObject {

    public static SimuladoModelo findByPK(int simuladoModeloCodigo, Connection conn) throws TransactionException {

        StringBuffer sbSql = new StringBuffer();
        sbSql.append("SELECT A.CD_SIMULADO         CD_SIMULADO         ");
        sbSql.append("     , A.CD_INSTITUICAO      CD_INSTITUICAO      ");
        sbSql.append("     , I.TX_NOME             TX_NOME_INSTITUICAO ");
        sbSql.append("     , A.CD_ORGAO            CD_ORGAO            ");
        sbSql.append("     , O.TX_NOME             TX_NOME_ORGAO       ");
        sbSql.append("     , A.TX_INDENTIFICACAO   TX_INDENTIFICACAO   ");
        sbSql.append("     , A.TX_DESCRICAO        TX_DESCRICAO        ");
        sbSql.append("     , A.TX_RESUMO           TX_RESUMO           ");
        sbSql.append("     , A.ID_NIVEL            ID_NIVEL            ");
        sbSql.append("     , A.ID_SITUACAO         ID_SITUACAO         ");
        sbSql.append("     , A.TS_CADASTRO         TS_CADASTRO         ");
        sbSql.append("  FROM SIMULADO_MODELO  A ");
        sbSql.append("  LEFT JOIN INSTITUICAO I ");
        sbSql.append("    ON A.CD_INSTITUICAO = I.CD_INSTITUICAO ");
        sbSql.append("  LEFT JOIN ORGAO       O ");
        sbSql.append("    ON A.CD_ORGAO       = O.CD_ORGAO ");
        sbSql.append(" WHERE A.CD_SIMULADO = ? ");

        SimuladoModelo simuladoModelo = null;
        try {
            PreparedStatement ps = conn.prepareStatement(sbSql.toString());
            setInt(ps, 1, simuladoModeloCodigo);
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                simuladoModelo = fromResultSet(rs);
            }
            close(ps);
        } catch (SQLException sqle) {
            throw new TransactionException("SimuladoModeloDAO.findByPK (" + sqle.getMessage() + ")");
        }
        return simuladoModelo;
    }

    public static List<SimuladoModelo> findAll(Connection conn) throws TransactionException {

        StringBuffer sbSql = new StringBuffer();
        sbSql.append("SELECT A.CD_SIMULADO         CD_SIMULADO         ");
        sbSql.append("     , A.CD_INSTITUICAO      CD_INSTITUICAO      ");
        sbSql.append("     , I.TX_NOME             TX_NOME_INSTITUICAO ");
        sbSql.append("     , A.CD_ORGAO            CD_ORGAO            ");
        sbSql.append("     , O.TX_NOME             TX_NOME_ORGAO       ");
        sbSql.append("     , A.TX_INDENTIFICACAO   TX_INDENTIFICACAO   ");
        sbSql.append("     , A.TX_DESCRICAO        TX_DESCRICAO        ");
        sbSql.append("     , A.TX_RESUMO           TX_RESUMO           ");
        sbSql.append("     , A.ID_NIVEL            ID_NIVEL            ");
        sbSql.append("     , A.ID_SITUACAO         ID_SITUACAO         ");
        sbSql.append("     , A.TS_CADASTRO         TS_CADASTRO         ");
        sbSql.append("  FROM SIMULADO_MODELO  A ");
        sbSql.append("  LEFT JOIN INSTITUICAO I ");
        sbSql.append("    ON A.CD_INSTITUICAO = I.CD_INSTITUICAO ");
        sbSql.append("  LEFT JOIN ORGAO       O ");
        sbSql.append("    ON A.CD_ORGAO       = O.CD_ORGAO ");
        sbSql.append(" ORDER BY A.CD_SIMULADO ");
        List<SimuladoModelo> simuladoModelosList = new ArrayList<SimuladoModelo>(100);
        try {
            PreparedStatement ps = conn.prepareStatement(sbSql.toString());
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                SimuladoModelo simuladoModelo = fromResultSet(rs);
                simuladoModelosList.add(simuladoModelo);
            }
            close(rs);
        } catch (SQLException sqle) {
            throw new TransactionException("SimuladoModeloDAO.findAll (" + sqle.getMessage() + ")");
        }
        return simuladoModelosList;
    }

    public static List<SimuladoModelo> findByFilter(SimuladoModeloFilter filter, Connection conn) throws TransactionException {

        StringBuffer sbSql = new StringBuffer();
        sbSql.append("SELECT A.CD_SIMULADO         CD_SIMULADO         ");
        sbSql.append("     , A.CD_INSTITUICAO      CD_INSTITUICAO      ");
        sbSql.append("     , I.TX_NOME             TX_NOME_INSTITUICAO ");
        sbSql.append("     , A.CD_ORGAO            CD_ORGAO            ");
        sbSql.append("     , O.TX_NOME             TX_NOME_ORGAO       ");
        sbSql.append("     , A.TX_INDENTIFICACAO   TX_INDENTIFICACAO   ");
        sbSql.append("     , A.TX_DESCRICAO        TX_DESCRICAO        ");
        sbSql.append("     , A.TX_RESUMO           TX_RESUMO           ");
        sbSql.append("     , A.ID_NIVEL            ID_NIVEL            ");
        sbSql.append("     , A.ID_SITUACAO         ID_SITUACAO         ");
        sbSql.append("     , A.TS_CADASTRO         TS_CADASTRO         ");
        sbSql.append("  FROM SIMULADO_MODELO  A ");
        sbSql.append("  LEFT JOIN INSTITUICAO I ");
        sbSql.append("    ON A.CD_INSTITUICAO = I.CD_INSTITUICAO ");
        sbSql.append("  LEFT JOIN ORGAO       O ");
        sbSql.append("    ON A.CD_ORGAO       = O.CD_ORGAO ");
        sbSql.append(" WHERE 1 = 1 ");
        if (filter.hasCodigoInstituicao()) {
            sbSql.append(" AND A.CD_INSTITUICAO = ? ");
        }
        if (filter.hasCodigoOrgao()) {
            sbSql.append(" AND A.CD_ORGAO = ? ");
        }
        if (filter.hasCodigoNivel()) {
            sbSql.append(" AND A.ID_NIVEL = ? ");
        }
        if (filter.hasCodigoSituacao()) {
            sbSql.append(" AND A.ID_SITUACAO = ? ");
        }
        sbSql.append(" ORDER BY A.TX_INDENTIFICACAO ");
        List<SimuladoModelo> simuladoModelosList = new ArrayList<SimuladoModelo>(100);
        try {
            PreparedStatement ps = conn.prepareStatement(sbSql.toString());
            int pos = 1;
            if (filter.hasCodigoInstituicao()) {
                setInt(ps, pos++, filter.getCodigoInstituicao());
            }
            if (filter.hasCodigoOrgao()) {
                setInt(ps, pos++, filter.getCodigoOrgao());
            }
            if (filter.hasCodigoNivel()) {
                setInt(ps, pos++, filter.getCodigoNivel());
            }
            if (filter.hasCodigoSituacao()) {
                setInt(ps, pos++, filter.getCodigoSituacao());
            }
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                SimuladoModelo simuladoModelo = fromResultSet(rs);
                simuladoModelosList.add(simuladoModelo);
            }
            close(rs);
        } catch (SQLException sqle) {
            throw new TransactionException("SimuladoModeloDAO.findByFilter (" + sqle.getMessage() + ")");
        }
        return simuladoModelosList;
    }

    public static void insert(SimuladoModelo simuladoModelo, Connection conn) throws TransactionException {

        StringBuffer sbSql = new StringBuffer();
        sbSql.append("INSERT INTO SIMULADO_MODELO     ");
        sbSql.append("     ( CD_SIMULADO       ");
        sbSql.append("     , CD_INSTITUICAO    ");
        sbSql.append("     , CD_ORGAO          ");
        sbSql.append("     , TX_INDENTIFICACAO ");
        sbSql.append("     , TX_DESCRICAO      ");
        sbSql.append("     , TX_RESUMO         ");
        sbSql.append("     , ID_NIVEL          ");
        sbSql.append("     , ID_SITUACAO       ");
        sbSql.append("     , TS_CADASTRO       ");
        sbSql.append(") VALUES (?,?,?,?,?,?,?,?,?)");
        try {
            PreparedStatement ps = conn.prepareStatement(sbSql.toString());
            int pos = 1;
            setInt(ps, pos++, simuladoModelo.getCodigo());
            setInt(ps, pos++, simuladoModelo.getInstituicao().getCodigo(), true);
            setInt(ps, pos++, simuladoModelo.getOrgao().getCodigo(), true);
            setString(ps, pos++, simuladoModelo.getIdentificacao());
            setString(ps, pos++, simuladoModelo.getDescricao());
            setString(ps, pos++, simuladoModelo.getResumo(), true);
            setInt(ps, pos++, simuladoModelo.getNivel().getCodigo(), true);
            setInt(ps, pos++, simuladoModelo.getSituacao().getCodigo());
            setTimestamp(ps, pos++, simuladoModelo.getDataCadastro());
            ps.executeUpdate();
            close(ps);
        } catch (SQLException sqle) {
            throw new TransactionException("SimuladoModeloDAO.insert (" + sqle.getMessage() + ")");
        }
    }
    

    public static void update(SimuladoModelo simuladoModelo, Connection conn) throws TransactionException {

        StringBuffer sbSql = new StringBuffer();
        sbSql.append("UPDATE SIMULADO_MODELO       ");
        sbSql.append("   SET CD_INSTITUICAO    = ? ");
        sbSql.append("     , CD_ORGAO          = ? ");
        sbSql.append("     , TX_INDENTIFICACAO = ? ");
        sbSql.append("     , TX_DESCRICAO      = ? ");
        sbSql.append("     , TX_RESUMO         = ? ");
        sbSql.append("     , ID_NIVEL          = ? ");
        sbSql.append("     , ID_SITUACAO       = ? ");
        sbSql.append(" WHERE CD_SIMULADO       = ? ");
        
        try {
            PreparedStatement ps = conn.prepareStatement(sbSql.toString());
            int pos = 1;
            setInt(ps, pos++, simuladoModelo.getInstituicao().getCodigo(), true);
            setInt(ps, pos++, simuladoModelo.getOrgao().getCodigo(), true);
            setString(ps, pos++, simuladoModelo.getIdentificacao());
            setString(ps, pos++, simuladoModelo.getDescricao());
            setString(ps, pos++, simuladoModelo.getResumo(), true);
            setInt(ps, pos++, simuladoModelo.getNivel().getCodigo(), true);
            setInt(ps, pos++, simuladoModelo.getSituacao().getCodigo());
            setInt(ps, pos++, simuladoModelo.getCodigo());
            ps.executeUpdate();
            close(ps);
        } catch (SQLException sqle) {
            throw new TransactionException("SimuladoModeloDAO.update (" + sqle.getMessage() + ")");
        }
    }

    public static void delete(SimuladoModelo simuladoModelo, Connection conn) throws TransactionException {

        StringBuffer sbSql = new StringBuffer();
        sbSql.append("DELETE FROM SIMULADO_MODELO ");
        sbSql.append(" WHERE CD_SIMULADO = ?");
        try {
            PreparedStatement ps = conn.prepareStatement(sbSql.toString());
            setInt(ps, 1, simuladoModelo.getCodigo());
            ps.executeUpdate();
            close(ps);
        } catch (SQLException sqle) {
            throw new TransactionException("SimuladoModeloDAO.delete (" + sqle.getMessage() + ")");
        }
    }

    public static int getNextCodigo(Connection conn, int iRange, int eRange) throws TransactionException {

        try {
            StringBuffer sbSql = new StringBuffer();
            sbSql.append("SELECT MAX(CD_SIMULADO) AS CD_MAX ");
            sbSql.append("  FROM SIMULADO_MODELO ");
            sbSql.append(" WHERE CD_SIMULADO > ? ");
            sbSql.append("   AND CD_SIMULADO < ? ");

            PreparedStatement ps = conn.prepareStatement(sbSql.toString());
            setInt(ps, 1, iRange);
            setInt(ps, 2, eRange);
            ResultSet rs = ps.executeQuery();
            int max = 0;
            if (rs.next()) {
                max = rs.getInt("CD_MAX");
            }
            close(rs);
            return (max != 0 ? max : iRange) + 1;
        } catch (SQLException sqlEx) {
            throw new TransactionException(sqlEx);
        }
    }

    private static SimuladoModelo fromResultSet(ResultSet rs) throws SQLException {

        // SIMULADO_MODELO
        SimuladoModelo simuladoModelo = new SimuladoModelo();
        simuladoModelo.setCodigo(getInt(rs, "CD_SIMULADO"));
        simuladoModelo.getInstituicao().setCodigo(getInt(rs, "CD_INSTITUICAO"));
        simuladoModelo.getInstituicao().setNome(getString(rs, "TX_NOME_INSTITUICAO"));
        simuladoModelo.getOrgao().setCodigo(getInt(rs, "CD_ORGAO"));
        simuladoModelo.getOrgao().setNome(getString(rs, "TX_NOME_ORGAO"));
        simuladoModelo.setIdentificacao(getString(rs, "TX_INDENTIFICACAO"));
        simuladoModelo.setDescricao(getString(rs, "TX_DESCRICAO"));
        simuladoModelo.setResumo(getString(rs, "TX_RESUMO"));
        simuladoModelo.setNivel(ConcursoNivel.getNivelById(getByte(rs, "ID_NIVEL")));
        simuladoModelo.setSituacao(Situacao.getSituacaoById(getByte(rs, "ID_SITUACAO")));
        simuladoModelo.setDataCadastro(getDateFromTimestamp(rs, "TS_CADASTRO"));
        //
        return simuladoModelo;
    }

}
